{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": true,
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001B[92m------------------------------------------------------------\u001B[0m\n",
      "                       \u001B[92mGPU Mode (cupy)\u001B[0m\n",
      "\u001B[92m------------------------------------------------------------\u001B[0m\n",
      "\n",
      "train loss: 2.308147736102234\n",
      "=== epoch:  1 , train acc:  0.161 , test acc:  0.176 time:  168.657484292984 ===\n",
      "train loss: 2.23054429774057\n",
      "train loss: 2.276814706812484\n",
      "train loss: 2.2360519120373374\n",
      "train loss: 2.2052077350695796\n",
      "train loss: 2.313619767016985\n",
      "train loss: 2.237711526022248\n",
      "train loss: 2.23452988756208\n",
      "train loss: 2.2438129703995937\n",
      "train loss: 2.199556584474562\n",
      "train loss: 2.242897328494754\n",
      "=== epoch:  2 , train acc:  0.427 , test acc:  0.426 time:  7.917654752731323 ===\n",
      "train loss: 2.1629563701226995\n",
      "train loss: 2.1551567644128555\n",
      "train loss: 2.131714205698484\n",
      "train loss: 2.115110094833308\n",
      "train loss: 2.1789530874132508\n",
      "train loss: 2.0271850367826927\n",
      "train loss: 2.1384551820379105\n",
      "train loss: 2.133780896617189\n",
      "train loss: 2.0699495883185035\n",
      "train loss: 2.0860351126242627\n",
      "=== epoch:  3 , train acc:  0.578 , test acc:  0.528 time:  7.75351095199585 ===\n",
      "train loss: 1.9175881074134526\n",
      "train loss: 2.043503009632939\n",
      "train loss: 1.9864197185711439\n",
      "train loss: 2.0644294447035856\n",
      "train loss: 1.9944352591547334\n",
      "train loss: 2.013963667206535\n",
      "train loss: 1.8291554385253657\n",
      "train loss: 1.8780419029324171\n",
      "train loss: 1.918747177977788\n",
      "train loss: 1.9490017889491822\n",
      "=== epoch:  4 , train acc:  0.672 , test acc:  0.627 time:  7.739468812942505 ===\n",
      "train loss: 2.012472292359584\n",
      "train loss: 1.8676546609513696\n",
      "train loss: 1.8268383923098974\n",
      "train loss: 1.7865882554937529\n",
      "train loss: 1.7908112751473684\n",
      "train loss: 1.9057501405405\n",
      "train loss: 1.923027593077565\n",
      "train loss: 1.9489540082862227\n",
      "train loss: 1.8800821652346857\n",
      "train loss: 1.906096316700985\n",
      "=== epoch:  5 , train acc:  0.725 , test acc:  0.647 time:  7.76503849029541 ===\n",
      "train loss: 1.8950229385410733\n",
      "train loss: 1.7899789925697274\n",
      "train loss: 1.9992774591431752\n",
      "train loss: 1.6672170422483001\n",
      "train loss: 1.8714398861682002\n",
      "train loss: 1.7946717791929439\n",
      "train loss: 1.7923260995332084\n",
      "train loss: 1.775692135323998\n",
      "train loss: 1.9035317032026753\n",
      "train loss: 1.871940368602799\n",
      "=== epoch:  6 , train acc:  0.811 , test acc:  0.725 time:  7.7583582401275635 ===\n",
      "train loss: 1.8125653701422035\n",
      "train loss: 1.7671048880306028\n",
      "train loss: 1.6541758354816805\n",
      "train loss: 1.7874465484372388\n",
      "train loss: 1.83163010074756\n",
      "train loss: 1.8027722174248857\n",
      "train loss: 1.7880396351347307\n",
      "train loss: 1.8374022625351734\n",
      "train loss: 1.5811896492697857\n",
      "train loss: 1.7185904653317277\n",
      "=== epoch:  7 , train acc:  0.839 , test acc:  0.741 time:  7.777924537658691 ===\n",
      "train loss: 1.792704767302185\n",
      "train loss: 1.6916555391349655\n",
      "train loss: 1.8120207829869868\n",
      "train loss: 1.5053572892341598\n",
      "train loss: 1.894515628318422\n",
      "train loss: 1.7407727619605708\n",
      "train loss: 1.6631801457395585\n",
      "train loss: 1.6874282913001277\n",
      "train loss: 1.6204433307070985\n",
      "train loss: 1.6868790761709314\n",
      "=== epoch:  8 , train acc:  0.884 , test acc:  0.796 time:  7.75685715675354 ===\n",
      "train loss: 1.7446928335286034\n",
      "train loss: 1.5679022311676827\n",
      "train loss: 1.7671422564005592\n",
      "train loss: 1.6807807110931292\n",
      "train loss: 1.7758959847491038\n",
      "train loss: 1.7379061296928233\n",
      "train loss: 1.8141893735259358\n",
      "train loss: 1.658650849021036\n",
      "train loss: 1.7058637894957551\n",
      "train loss: 1.6456008485117144\n",
      "=== epoch:  9 , train acc:  0.864 , test acc:  0.785 time:  7.7623937129974365 ===\n",
      "train loss: 1.7532047633749317\n",
      "train loss: 1.6698702460610746\n",
      "train loss: 1.4620804938157719\n",
      "train loss: 1.3733673932213082\n",
      "train loss: 1.5949958472247416\n",
      "train loss: 1.745741985460455\n",
      "train loss: 1.5638328227681277\n",
      "train loss: 1.5498910846029008\n",
      "train loss: 1.6061931609235807\n",
      "train loss: 1.7446301604078747\n",
      "=== epoch:  10 , train acc:  0.909 , test acc:  0.839 time:  7.746673822402954 ===\n",
      "train loss: 1.503118269269536\n",
      "train loss: 1.8052986104153532\n",
      "train loss: 1.5247786402203787\n",
      "train loss: 1.6399965533391847\n",
      "train loss: 1.5944539374933044\n",
      "train loss: 1.8172367899072686\n",
      "train loss: 1.504636443435925\n",
      "train loss: 1.679816562585123\n",
      "train loss: 1.5354464357731026\n",
      "========== Final Test Accuracy ================\n",
      "test acc: 0.8388\n",
      "Saved Network Parameters!\n"
     ]
    }
   ],
   "source": [
    "\n",
    "import matplotlib.pyplot as plt\n",
    "import numpy as np\n",
    "\n",
    "from dataset.mnist import load_mnist\n",
    "from common.optimizer import *\n",
    "from common.deep_convnet import DeepConvNet\n",
    "from common.trainer import Trainer\n",
    "\n",
    "# 0.读入MNIST数据\n",
    "(x_train, t_train), (x_test, t_test) = load_mnist(flatten=False)\n",
    "\n",
    "# 减少学习数据\n",
    "x_train = x_train[:1000]\n",
    "t_train = t_train[:1000]\n",
    "\n",
    "x_train = np.array(x_train)\n",
    "t_train = np.array(t_train)\n",
    "x_test = np.array(x_test)\n",
    "t_test = np.array(t_test)\n",
    "\n",
    "# 设置是否使用Dropout及比例\n",
    "max_epochs = 10\n",
    "\n",
    "network = DeepConvNet()\n",
    "trainer = Trainer(network, x_train, t_train, x_test, t_test,\n",
    "                  epochs=max_epochs, mini_batch_size=100,\n",
    "                  optimizer='Adam', optimizer_param={'lr': 0.001},\n",
    "                  evaluate_sample_num_per_epoch=1000)\n",
    "\n",
    "# 开始训练\n",
    "trainer.train()\n",
    "# 保存训练结果\n",
    "network.save_params(\"params.pkl\")\n",
    "print(\"Saved Network Parameters!\")\n",
    "\n",
    "# 绘制图像\n",
    "# markers = {\"train\": \"o\", \"test\": \"s\"}\n",
    "# x = np.arange(max_epochs)\n",
    "# plt.plot(x, trainer.train_acc_list, marker='o', label='train', markevery=2)\n",
    "# plt.plot(x, trainer.test_acc_list, marker='s', label='test', markevery=2)\n",
    "# plt.xlabel(\"epochs\")\n",
    "# plt.ylabel(\"accuracy\")\n",
    "# plt.ylim(0, 1.0)\n",
    "# plt.legend(loc='lower right')\n",
    "# plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'cupy.ndarray'>\n",
      "10\n",
      "[array(0.161), array(0.427), array(0.578), array(0.672), array(0.725), array(0.811), array(0.839), array(0.884), array(0.864), array(0.909)]\n",
      "<class 'numpy.ndarray'>\n"
     ]
    }
   ],
   "source": [
    "# cupy数组转numpy数组\n",
    "print(type(trainer.train_acc_list[0]))\n",
    "print(len(trainer.train_acc_list))\n",
    "print(trainer.train_acc_list)\n",
    "train_acc_list = [x.get() for x in trainer.train_acc_list]\n",
    "print(type(train_acc_list[0]))"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1 2 3 4 5]\n",
      "<class 'cupy.ndarray'>\n",
      "5\n",
      "<class 'float'>\n"
     ]
    }
   ],
   "source": [
    "import cupy as cp\n",
    "\n",
    "cupy_array = cp.array([1, 2, 3, 4,5])\n",
    "print(cupy_array)\n",
    "print(type(cupy_array))\n",
    "print(cupy_array.shape[0])\n",
    "print(type(1.0 / cupy_array.shape[0]))"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "outputs": [
    {
     "data": {
      "text/plain": "<Figure size 640x480 with 1 Axes>",
      "image/png": "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Nm0aeXl5jBo1CoARI0bQrFkzpkyZAsBDDz3ERRddxNSpUxk8eDCffPIJK1as4O2337by2xAREZFawvJwM2zYMA4cOMD48eNJTU2lW7duzJs3r2zS8J49e8otxdy3b18++ugjnnjiCR577DHatm3LV199RefOna36Fsr4+PgwYcKEE4bBxBr6fdQu+n3ULvp91D76nbiO5evciIiIiLiS5SsUi4iIiLiSwo2IiIi4FYUbERERcSsKNyIiIuJWFG5c5PXXXyc6OhpfX1969+7NsmXLrC6p3poyZQq9evUiICCAJk2aMHToUDZv3mx1WXLEc889h81m4+GHH7a6lHpr37593HrrrYSGhuLn50dsbCwrVqywuqx6yeFw8OSTTxITE4Ofnx+tW7fm6aefrtD+SXJqCjcuMGvWLBISEpgwYQKrVq2ia9euDBw4kPT0dKtLq5cWLVrEfffdxx9//MH8+fMpKSlhwIAB5OXlWV1avbd8+XLeeustunTpYnUp9dbhw4c577zz8Pb25vvvv2fDhg1MnTqVRo0aWV1avfT888/z5ptvMn36dDZu3Mjzzz/PCy+8wGuvvWZ1aXWabgV3gd69e9OrVy+mT58OmKssR0VF8cADDzB27FiLq5MDBw7QpEkTFi1axIUXXmh1OfVWbm4uPXr04I033uCZZ56hW7duTJs2zeqy6p2xY8eyePFifv31V6tLEeDKK68kPDyc//73v2Vt1113HX5+fnz44YcWVla3qeemioqLi1m5ciX9+vUra/Pw8KBfv34sWbLEwsrkqKysLABCQkIsrqR+u++++xg8eHC5/1ak5n3zzTfExcVxww030KRJE7p3784777xjdVn1Vt++fUlMTGTLli0ArF69mt9++43LL7/c4srqNstXKK7rMjIycDgcZSsqHxUeHs6mTZssqkqOcjqdPPzww5x33nm1YhXr+uqTTz5h1apVLF++3OpS6r0dO3bw5ptvkpCQwGOPPcby5ct58MEHsdvtjBw50ury6p2xY8eSnZ1N+/bt8fT0xOFw8Oyzz3LLLbdYXVqdpnAjbu2+++5j3bp1/Pbbb1aXUm8lJyfz0EMPMX/+fHx9fa0up95zOp3ExcUxefJkALp37866deuYMWOGwo0FPv30U/73v//x0Ucf0alTJ5KSknj44Ydp2rSpfh9VoHBTRWFhYXh6epKWllauPS0tjYiICIuqEoD777+f7777jl9++YXmzZtbXU69tXLlStLT0+nRo0dZm8Ph4JdffmH69OkUFRXh6elpYYX1S2RkJB07dizX1qFDB7744guLKqrfHn30UcaOHctNN90EQGxsLLt372bKlCkKN1WgOTdVZLfb6dmzJ4mJiWVtTqeTxMRE+vTpY2Fl9ZdhGNx///3Mnj2bBQsWEBMTY3VJ9dpll13G2rVrSUpKKnvExcVxyy23kJSUpGBTw84777wTlkbYsmULLVu2tKii+i0/P7/c5tAAnp6eOJ1OiypyD+q5cYGEhARGjhxJXFwc8fHxTJs2jby8PEaNGmV1afXSfffdx0cffcTXX39NQEAAqampAAQFBeHn52dxdfVPQEDACfOdGjRoQGhoqOZBWWD06NH07duXyZMnc+ONN7Js2TLefvtt3n77batLq5eGDBnCs88+S4sWLejUqRN//vknL7/8MnfccYfVpdVpuhXcRaZPn86LL75Iamoq3bp149///je9e/e2uqx6yWaznbT93Xff5fbbb6/ZYuSkLr74Yt0KbqHvvvuOcePGsXXrVmJiYkhISODuu++2uqx6KScnhyeffJLZs2eTnp5O06ZNGT58OOPHj8dut1tdXp2lcCMiIiJuRXNuRERExK0o3IiIiIhbUbgRERERt6JwIyIiIm5F4UZERETcisKNiIiIuBWFGxEREXErCjciUu8sXLgQm81GZmam1aWISDVQuBERERG3onAjIiIibkXhRkRqnNPpZMqUKcTExODn50fXrl35/PPPgWNDRnPmzKFLly74+vpy7rnnsm7dunLX+OKLL+jUqRM+Pj5ER0czderUcq8XFRUxZswYoqKi8PHxoU2bNvz3v/8td8zKlSuJi4vD39+fvn37ltste/Xq1VxyySUEBAQQGBhIz549WbFiRTX9RETElRRuRKTGTZkyhQ8++IAZM2awfv16Ro8eza233sqiRYvKjnn00UeZOnUqy5cvp3HjxgwZMoSSkhLADCU33ngjN910E2vXruWpp57iySef5L333is7f8SIEXz88cf8+9//ZuPGjbz11ls0bNiwXB2PP/44U6dOZcWKFXh5eZXbifmWW26hefPmLF++nJUrVzJ27Fi8vb2r9wcjIq5hiIjUoMLCQsPf39/4/fffy7XfeeedxvDhw42ff/7ZAIxPPvmk7LWDBw8afn5+xqxZswzDMIybb77Z6N+/f7nzH330UaNjx46GYRjG5s2bDcCYP3/+SWs4+h4//fRTWducOXMMwCgoKDAMwzACAgKM9957r+rfsIjUOPXciEiN2rZtG/n5+fTv35+GDRuWPT744AO2b99edlyfPn3Kvg4JCeGcc85h48aNAGzcuJHzzjuv3HXPO+88tm7disPhICkpCU9PTy666KLT1tKlS5eyryMjIwFIT08HICEhgbvuuot+/frx3HPPlatNRGo3hRsRqVG5ubkAzJkzh6SkpLLHhg0byubdVJWfn1+Fjjt+mMlmswHmfCCAp556ivXr1zN48GAWLFhAx44dmT17tkvqE5HqpXAjIjWqY8eO+Pj4sGfPHtq0aVPuERUVVXbcH3/8Ufb14cOH2bJlCx06dACgQ4cOLF68uNx1Fy9eTLt27fD09CQ2Nhan01luDk9ltGvXjtGjR/Pjjz9y7bXX8u6771bpeiJSM7ysLkBE6peAgAAeeeQRRo8ejdPp5PzzzycrK4vFixcTGBhIy5YtAZg0aRKhoaGEh4fz+OOPExYWxtChQwH45z//Sa9evXj66acZNmwYS5YsYfr06bzxxhsAREdHM3LkSO644w7+/e9/07VrV3bv3k16ejo33njjGWssKCjg0Ucf5frrrycmJoa9e/eyfPlyrrvuumr7uYiIC1k96UdE6h+n02lMmzbNOOeccwxvb2+jcePGxsCBA41FixaVTfb99ttvjU6dOhl2u92Ij483Vq9eXe4an3/+udGxY0fD29vbaNGihfHiiy+We72goMAYPXq0ERkZadjtdqNNmzbGzJkzDcM4NqH48OHDZcf/+eefBmDs3LnTKCoqMm666SYjKirKsNvtRtOmTY3777+/bLKxiNRuNsMwDIvzlYhImYULF3LJJZdw+PBhgoODrS5HROogzbkRERERt6JwIyIiIm5Fw1IiIiLiVtRzIyIiIm5F4UZERETcisKNiIiIuBWFGxEREXErCjciIiLiVhRuRERExK0o3IiIiIhbUbgRERERt6JwIyIiIm7l/wGMR2J7cYd54AAAAABJRU5ErkJggg=="
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 绘制图像\n",
    "import numpy as np\n",
    "markers = {\"train\": \"o\", \"test\": \"s\"}\n",
    "x = np.arange(max_epochs)\n",
    "plt.plot(x, [x.get() for x in trainer.train_acc_list], marker='o', label='train', markevery=2)\n",
    "plt.plot(x, [x.get() for x in trainer.test_acc_list], marker='s', label='test', markevery=2)\n",
    "plt.xlabel(\"epochs\")\n",
    "plt.ylabel(\"accuracy\")\n",
    "plt.ylim(0, 1.0)\n",
    "plt.legend(loc='lower right')\n",
    "plt.show()"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "duration:  0.001001596450805664 seconds\n"
     ]
    }
   ],
   "source": [
    "from common.np import *\n",
    "\n",
    "#import numpy as np\n",
    "import time\n",
    "\n",
    "start_time = time.time()\n",
    "x = np.ones((100, 1000, 1000))\n",
    "x1 = 5 * x\n",
    "x2 = x1 * x1\n",
    "end_time = time.time()\n",
    "print('duration: ', end_time - start_time, 'seconds')"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "outputs": [],
   "source": [
    "import cupy as cp\n",
    "import numpy as np\n",
    "\n",
    "# 创建一个 CuPy 数组\n",
    "cupy_array = cp.array([1, 2, 3, 4, 5])\n",
    "\n",
    "# 显式转换为 NumPy 数组\n",
    "numpy_array = cupy_array.get()\n",
    "\n",
    "# 验证转换结果\n",
    "print(type(numpy_array))  # <class 'numpy.ndarray'>\n",
    "print(numpy_array)  # [1 2 3 4 5]\n"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}